/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.classic.common.simple;

import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

import java.math.BigDecimal;
import java.util.ArrayList;

/**
 * BallClipRotateMultipleIndicator
 *
 * @since 2021-05-13
 */
public class BallClipRotateMultipleIndicator extends LoadingIndicatorView {
    private static final  int  num = 2;
    private static final  int num90 = 90;
    private static float scaleFloat = 1;
    private static float degrees;
    private static final int num12 = 2;
    private static final int num360 = 360;
    private static final float f18 = 1.8f;
    private static final float f08 = 0.8f;
    private static final float f05 = 0.5f;
    private static final float f02 = 0.2f;
    private static final int num1000 = 1000;
    private static final int num135 = 135;
    private static final int num45 = 1000;
    private static final int num720 = 720;
    private static final int num225 = 225;

    /**
     * BallClipRotateMultipleIndicator
     *
     * @param context context
     */
    public BallClipRotateMultipleIndicator(Context context) {
        super(context);
        init();
    }

    /**
     * 构造方法
     *
     * @param context
     * @param attrs
     */
    public BallClipRotateMultipleIndicator(Context context, AttrSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        Component.DrawTask task = (component, canvas) -> {
            setPaint();
            setBound();
            draw(canvas, getPaint());
        };
        addDrawTask(task);
    }

    @Override
    public void addDrawTask(DrawTask drawTask) {
        super.addDrawTask(drawTask);
        drawTask.onDraw(this, mCanvasForTaskOverContent);
    }

    @Override
    public void draw(Canvas canvas, Paint paint) {
        float x1 = (float) getWidth()/num;
        float y1 =(float)getHeight()/num;
        canvas.rotate(degrees * num360, x1,y1);

        paint.setStrokeWidth(num);
        paint.setStyle(Paint.Style.STROKE_STYLE);
        float circleSpacing = num12;

        canvas.save();
        canvas.translate(x1, y1);
        canvas.scale(scaleFloat, scaleFloat);

        float[] startAngles = new float[]{num135, -num45};
        for (int i1 = 0; i1 < num; i1++) {
            RectFloat rectF = new RectFloat(-x1 + circleSpacing, -y1 + circleSpacing, x1 - circleSpacing,
                    y1 - circleSpacing);

            canvas.drawArc(rectF, new Arc(startAngles[i1], num90, false), paint);
        }

        canvas.restore();

        canvas.rotate(-degrees * num720, (float) getWidth() / num, (float)getHeight() / num);

        canvas.translate(x1, y1);
        canvas.scale(scaleFloat, scaleFloat);

        float[] sStartAngles = new float[]{num225, num45};
        for (int i2 = 0; i2 < num; i2++) {
            float left = -x1 / f18 + circleSpacing;
            float right = x1 / f18 - circleSpacing;
            RectFloat rectF = new RectFloat(left, -y1 / f18 + circleSpacing, right, y1 / f18 - circleSpacing);
            canvas.drawArc(rectF, new Arc(sStartAngles[i2], num90, false), paint);
        }
    }

    @Override
    public ArrayList<AnimatorValue> onCreateAnimators() {
        AnimatorValue scaleAnim = new AnimatorValue();
        scaleAnim.setDuration(num1000);
        scaleAnim.setLoopedCount(-(int) scaleFloat);
        addUpdateListener(scaleAnim, (animatorValue, v1) -> {
            if (v1 < f05) {
                scaleFloat = -f08 * v1 + (int) scaleFloat;
            } else {
                scaleFloat = f08 * v1 + f02;
            }
            invalidate();
        });

        AnimatorValue rotateAnim = new AnimatorValue();
        rotateAnim.setDuration(num1000);
        rotateAnim.setLoopedCount(-(int) scaleFloat);
        addUpdateListener(rotateAnim, (animatorValue, v1) -> {
            degrees = v1;
            invalidate();
        });
        ArrayList<AnimatorValue> animators = new ArrayList<>();
        animators.add(scaleAnim);
        animators.add(rotateAnim);
        return animators;
    }
}
